package zy.service.batch.sell.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import zy.dao.approve.ApproveRecordDAO;
import zy.dao.base.product.ProductDAO;
import zy.dao.base.size.SizeDAO;
import zy.dao.base.stream.StreamBillDAO;
import zy.dao.batch.client.ClientDAO;
import zy.dao.batch.dealings.BatchDealingsDAO;
import zy.dao.batch.sell.BatchSellDAO;
import zy.dao.batch.settle.BatchSettleDAO;
import zy.dao.stock.data.DataDAO;
import zy.dao.stock.useable.UseableDAO;
import zy.dao.sys.print.PrintDAO;
import zy.dto.common.ProductDto;
import zy.entity.PageData;
import zy.entity.PageInfo;
import zy.entity.approve.T_Approve_Record;
import zy.entity.base.product.T_Base_Barcode;
import zy.entity.base.product.T_Base_Product;
import zy.entity.base.size.T_Base_Size;
import zy.entity.base.size.T_Base_SizeList;
import zy.entity.base.stream.T_Base_Stream;
import zy.entity.base.stream.T_Base_Stream_Bill;
import zy.entity.batch.client.T_Batch_Client;
import zy.entity.batch.client.T_Batch_ClientPrice;
import zy.entity.batch.dealings.T_Batch_Dealings;
import zy.entity.batch.order.T_Batch_Import;
import zy.entity.batch.order.T_Batch_Order;
import zy.entity.batch.sell.T_Batch_Sell;
import zy.entity.batch.sell.T_Batch_SellList;
import zy.entity.batch.settle.T_Batch_SettleList;
import zy.entity.stock.data.T_Stock_DataBill;
import zy.entity.sys.set.T_Sys_Set;
import zy.entity.sys.user.T_Sys_User;
import zy.service.batch.sell.BatchSellService;
import zy.util.CommonUtil;
import zy.util.DateUtil;
import zy.util.StringUtil;
import zy.vo.batch.BatchSellVO;
import zy.vo.common.SizeHorizontalVO;

@Service
public class BatchSellServiceImpl implements BatchSellService{
	@Resource
	private BatchSellDAO batchSellDAO;
	
	@Resource
	private SizeDAO sizeDAO;
	
	@Resource
	private ApproveRecordDAO approveRecordDAO;
	
	@Resource
	private DataDAO dataDAO;
	
	@Resource
	private BatchDealingsDAO batchDealingsDAO;
	
	@Resource
	private BatchSettleDAO batchSettleDAO;
	
	@Resource
	private StreamBillDAO streamBillDAO;
	
	@Resource
	private PrintDAO printDAO;
	
	@Resource
	private ClientDAO clientDAO;
	
	@Resource
	private UseableDAO useableDAO;
	
	@Resource
	private ProductDAO productDAO;

	@Override
	public PageData<T_Batch_Sell> page(Map<String, Object> params) {
		Assert.notNull(params.get(CommonUtil.COMPANYID),"连接超时，请重新登录!");
		Integer _pageSize = (Integer)params.get(CommonUtil.PAGESIZE);
		Integer _pageIndex = (Integer)params.get(CommonUtil.PAGEINDEX);
		
		Map<String, Object> sumMap = batchSellDAO.countSum(params);
		int totalCount = Integer.parseInt(sumMap.get("totalCount").toString());
		PageInfo pageInfo = new PageInfo(totalCount, _pageSize, _pageIndex);
		params.put(CommonUtil.START, (_pageIndex-1)*_pageSize);
		params.put(CommonUtil.END, _pageSize);
		
		List<T_Batch_Sell> list = batchSellDAO.list(params);
		PageData<T_Batch_Sell> pageData = new PageData<T_Batch_Sell>();
		pageData.setPageInfo(pageInfo);
		pageData.setList(list);
		pageData.setData(sumMap);
		return pageData;
	}
	
	@Override
	public List<T_Batch_Sell> listExport(Map<String, Object> params) {
		Assert.notNull(params.get(CommonUtil.COMPANYID),"连接超时，请重新登录!");
		params.put(CommonUtil.START, 0);
		params.put(CommonUtil.END, Integer.MAX_VALUE);
		return batchSellDAO.list(params);
	}
	
	@Override
	public T_Batch_Sell load(Integer se_id) {
		T_Batch_Sell order = batchSellDAO.load(se_id);
		if(order != null){
			T_Approve_Record approve_Record = approveRecordDAO.load(order.getSe_number(), order.getCompanyid());
			if(approve_Record != null){
				order.setAr_describe(approve_Record.getAr_describe());
			}
		}
		return order;
	}
	
	@Override
	public T_Batch_Sell load(String number,Integer companyid) {
		return batchSellDAO.load(number, companyid);
	}
	
	@Override
	public List<T_Batch_SellList> detail_list(Map<String, Object> params) {
		return batchSellDAO.detail_list(params);
	}
	
	@Override
	public List<T_Batch_SellList> detail_sum(Map<String, Object> params) {
		return batchSellDAO.detail_sum(params);
	}
	
	@Override
	public Map<String, Object> detail_size_title(Map<String, Object> params) {
		Integer companyid = (Integer)params.get(CommonUtil.COMPANYID);
		List<String> szgCodes = batchSellDAO.detail_szgcode(params);
		if(szgCodes==null||szgCodes.size()==0){
			Map<String, Object> resultMap = new HashMap<String, Object>();
			resultMap.put("titles", new ArrayList<List<String>>());
			return resultMap;
		}
		List<T_Base_SizeList> sizeGroupList = sizeDAO.listBySzg(szgCodes, companyid);
		return SizeHorizontalVO.getJsonSizeTitles(sizeGroupList);
	}
	
	@Override
	public Map<String, Object> detail_size(Map<String, Object> params) {
		Integer companyid = (Integer)params.get(CommonUtil.COMPANYID);
		List<String> szgCodes = batchSellDAO.detail_szgcode(params);
		if(szgCodes==null||szgCodes.size()==0){
			return new HashMap<String, Object>();
		}
		List<T_Base_SizeList> sizeGroupList = sizeDAO.listBySzg(szgCodes, companyid);
		params.put(CommonUtil.SIDX, "sel_pd_code,sel_pi_type,sel_cr_code,sel_br_code");
		params.put(CommonUtil.SORD, "ASC");
		List<T_Batch_SellList> temps = batchSellDAO.detail_list(params);
		return BatchSellVO.getJsonSizeData(sizeGroupList, temps);
	}

	@Override
	public List<T_Batch_SellList> temp_list(Map<String, Object> params) {
		return batchSellDAO.temp_list(params);
	}

	@Override
	public List<T_Batch_SellList> temp_sum(Integer se_type, Integer us_id, Integer companyid) {
		return batchSellDAO.temp_sum(se_type, us_id, companyid);
	}

	@Override
	public Map<String, Object> temp_size_title(Map<String, Object> params) {
		Integer companyid = (Integer)params.get(CommonUtil.COMPANYID);
		List<String> szgCodes = batchSellDAO.temp_szgcode(params);
		if(szgCodes==null||szgCodes.size()==0){
			Map<String, Object> resultMap = new HashMap<String, Object>();
			resultMap.put("titles", new ArrayList<List<String>>());
			return resultMap;
		}
		List<T_Base_SizeList> sizeGroupList = sizeDAO.listBySzg(szgCodes, companyid);
		return SizeHorizontalVO.getJsonSizeTitles(sizeGroupList);
	}

	@Override
	public Map<String, Object> temp_size(Map<String, Object> params) {
		Integer companyid = (Integer)params.get(CommonUtil.COMPANYID);
		List<String> szgCodes = batchSellDAO.temp_szgcode(params);
		if(szgCodes==null||szgCodes.size()==0){
			return new HashMap<String, Object>();
		}
		List<T_Base_SizeList> sizeGroupList = sizeDAO.listBySzg(szgCodes, companyid);
		params.put(CommonUtil.SIDX, "sel_pd_code,sel_pi_type,sel_cr_code,sel_br_code");
		params.put(CommonUtil.SORD, "ASC");
		List<T_Batch_SellList> temps = batchSellDAO.temp_list(params);
		return BatchSellVO.getJsonSizeData(sizeGroupList, temps);
	}
	
	@Override
	public PageData<T_Base_Product> page_product(Map<String, Object> param) {
		Assert.notNull(param.get(CommonUtil.COMPANYID),"连接超时，请重新登录!");
		Integer _pageSize = (Integer)param.get(CommonUtil.PAGESIZE);
		Integer _pageIndex = (Integer)param.get(CommonUtil.PAGEINDEX);
		
		Integer totalCount = batchSellDAO.count_product(param);
		PageInfo pageInfo = new PageInfo(totalCount, _pageSize, _pageIndex);
		param.put(CommonUtil.START, (_pageIndex-1)*_pageSize);
		param.put(CommonUtil.END, _pageSize);
		
		List<T_Base_Product> list = batchSellDAO.list_product(param);
		PageData<T_Base_Product> pageData = new PageData<T_Base_Product>();
		pageData.setPageInfo(pageInfo);
		pageData.setList(list);
		return pageData;
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public Map<String, Object> temp_loadproduct(Map<String, Object> params) {
		Assert.notNull(params.get(CommonUtil.COMPANYID),"连接超时，请重新登录!");
		Integer companyid = (Integer)params.get(CommonUtil.COMPANYID);
		T_Sys_Set sysSet = (T_Sys_Set)params.get(CommonUtil.KEY_SYSSET);
		Integer us_id = (Integer)params.get("us_id");
		String pd_code = (String)params.get("pd_code");
		String dp_code = (String)params.get("dp_code");
		String ci_code = (String)params.get("ci_code");
		String priceType = (String)params.get("priceType");
		Double ci_rate = (Double)params.get("ci_rate");
		String batch_price = (String)params.get("batch_price");
		Integer se_type = (Integer)params.get("se_type");
		String exist = (String)params.get("exist");
		String sel_pi_type = (String)params.get("sel_pi_type");
		Map<String, Object> resultMap = new HashMap<String, Object>();
		T_Base_Product base_Product = batchSellDAO.load_product(pd_code, companyid);
		Double lastBatchPrice = batchSellDAO.queryLastBatchPrice(pd_code, ci_code, companyid);
		if(lastBatchPrice==null){
			lastBatchPrice = base_Product.getPd_batch_price();
		}
		Map<String, Object> product = new HashMap<String, Object>();
		product.put("pd_id", base_Product.getPd_id());
		product.put("pd_code", base_Product.getPd_code());
		product.put("pd_no", base_Product.getPd_no());
		product.put("pd_name", base_Product.getPd_name());
		product.put("pd_szg_code", base_Product.getPd_szg_code());
		product.put("pd_unit", base_Product.getPd_unit());
		product.put("pd_year", base_Product.getPd_year());
		product.put("pd_season", base_Product.getPd_season());
		product.put("pd_sell_price", base_Product.getPd_sell_price());
		product.put("pd_cost_price", base_Product.getPd_cost_price());
		product.put("pd_batch_price", base_Product.getPd_batch_price());
		product.put("pd_batch_price1", base_Product.getPd_batch_price1());
		product.put("pd_batch_price2", base_Product.getPd_batch_price2());
		product.put("pd_batch_price3", base_Product.getPd_batch_price3());
		product.put("pd_bd_name", base_Product.getPd_bd_name());
		product.put("pd_tp_name", base_Product.getPd_tp_name());
		product.put("last_batch_price", lastBatchPrice);
		product.put("pdm_img_path", StringUtil.trimString(base_Product.getPdm_img_path()));
		Double unitPrice = null;
		if("1".equals(exist)){//已经录入从临时表中查询单价
			T_Batch_SellList temp_price = batchSellDAO.temp_queryUnitPrice(pd_code,sel_pi_type, se_type, us_id, companyid);
			if (temp_price != null) {
				unitPrice = temp_price.getSel_unitprice();
				product.put("temp_unitPrice", StringUtil.trimString(unitPrice));
				product.put("temp_rebatePrice", StringUtil.trimString(temp_price.getSel_rebateprice()));
			}
		}
		if(unitPrice == null){
			if("1".equals(priceType)){//最近批发价
				unitPrice = lastBatchPrice;
			}else if("2".equals(priceType)){//按照折扣率
				unitPrice = base_Product.getPd_sell_price() * ci_rate;
			}else if("3".equals(priceType)){//批发价
				if("0".equals(batch_price)){
					unitPrice = base_Product.getPd_batch_price();
				}else if("1".equals(batch_price)){
					unitPrice = base_Product.getPd_batch_price1();
				}else if("2".equals(batch_price)){
					unitPrice = base_Product.getPd_batch_price2();
				}else if("3".equals(batch_price)){
					unitPrice = base_Product.getPd_batch_price3();
				}else {
					unitPrice = base_Product.getPd_batch_price();
				}
			}
		}
		product.put("unitPrice", unitPrice);
		resultMap.put("product", product);
		params.put("szg_code", base_Product.getPd_szg_code());
		Map<String, Object> productMap = batchSellDAO.load_product_size(params);
		List<T_Base_Size> sizes=(List<T_Base_Size>)productMap.get("sizes");
		List<ProductDto> inputs=(List<ProductDto>)productMap.get("inputs");
		List<ProductDto> temps=(List<ProductDto>)productMap.get("temps");
		List<ProductDto> stocks=(List<ProductDto>)productMap.get("stocks");
		Map<String,Object> usableStockMap = null;
		if (sysSet.getSt_useable() != null && sysSet.getSt_useable().intValue() == 1) {
			usableStockMap = useableDAO.loadUseableStock(pd_code, dp_code, companyid);
		}
		resultMap.putAll(SizeHorizontalVO.buildJsonProductInput(pd_code, sizes, inputs, stocks, temps, usableStockMap));
		return resultMap;
	}
	
	@Override
	@Transactional
	public Map<String, Object> temp_save_bybarcode(Map<String, Object> params) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		Integer se_type = (Integer)params.get("se_type");
		String barcode = (String)params.get("barcode");
		Integer amount = (Integer)params.get("amount");
		String ci_code = (String)params.get("ci_code");
		String priceType = (String)params.get("priceType");
		Double ci_rate = (Double)params.get("ci_rate");
		String batch_price = (String)params.get("batch_price");
		T_Sys_User user = (T_Sys_User)params.get("user");
		T_Base_Barcode base_Barcode = productDAO.loadBarcode(barcode, user.getCompanyid());
		if(base_Barcode == null){
			resultMap.put("result", 3);//条码不存在
			return resultMap;
		}
		T_Batch_SellList temp = batchSellDAO.temp_loadBySubCode(base_Barcode.getBc_subcode(), "0", se_type, user.getUs_id(), user.getCompanyid());
		if (temp != null) {//临时表存在则直接更新数量
			temp.setSel_amount(temp.getSel_amount()+amount);
			batchSellDAO.temp_update(temp);
			resultMap.put("result", 1);//update
			resultMap.put("temp", temp);
			return resultMap;
		}
		T_Base_Product base_Product = batchSellDAO.load_product(base_Barcode.getBc_pd_code(), user.getCompanyid());
		T_Batch_SellList temp_price= batchSellDAO.temp_queryUnitPrice(base_Barcode.getBc_pd_code(),"0", se_type, user.getUs_id(), user.getCompanyid());;
		Double unitPrice = null;
		Double rebatePrice = 0d;
		if(temp_price != null){
			unitPrice = temp_price.getSel_unitprice();
			rebatePrice = temp_price.getSel_rebateprice();
		}else {
			if("1".equals(priceType)){//最近批发价
				Double lastBatchPrice = batchSellDAO.queryLastBatchPrice(base_Barcode.getBc_pd_code(), ci_code, user.getCompanyid());
				if (lastBatchPrice == null) {
					lastBatchPrice = base_Product.getPd_batch_price();
				}
				unitPrice = lastBatchPrice;
			}else if("2".equals(priceType)){//按照折扣率
				unitPrice = base_Product.getPd_sell_price() * ci_rate;
			}else if("3".equals(priceType)){//批发价
				if("0".equals(batch_price)){
					unitPrice = base_Product.getPd_batch_price();
				}else if("1".equals(batch_price)){
					unitPrice = base_Product.getPd_batch_price1();
				}else if("2".equals(batch_price)){
					unitPrice = base_Product.getPd_batch_price2();
				}else if("3".equals(batch_price)){
					unitPrice = base_Product.getPd_batch_price3();
				}else {
					unitPrice = base_Product.getPd_batch_price();
				}
			}
		}
		
		temp = new T_Batch_SellList();
		temp.setSel_pd_code(base_Barcode.getBc_pd_code());
		temp.setSel_cr_code(base_Barcode.getBc_color());
		temp.setSel_sz_code(base_Barcode.getBc_size());
		temp.setSel_szg_code(base_Product.getPd_szg_code());
		temp.setSel_br_code(base_Barcode.getBc_bra());
		temp.setSel_sub_code(temp.getSel_pd_code()+temp.getSel_cr_code()+temp.getSel_sz_code()+temp.getSel_br_code());
		temp.setSel_amount(amount);
		temp.setSel_unitprice(unitPrice);
		temp.setSel_retailprice(base_Product.getPd_sell_price());
		temp.setSel_costprice(base_Product.getPd_cost_price());
		temp.setSel_rebateprice(rebatePrice);
		temp.setSel_remark("");
		temp.setSel_pi_type(0);//商品
		temp.setSel_type(se_type);
		temp.setSel_us_id(user.getUs_id());
		temp.setCompanyid(user.getCompanyid());
		batchSellDAO.temp_save(temp);
		temp.setPd_no(base_Product.getPd_no());
		temp.setPd_name(base_Product.getPd_name());
		temp.setPd_unit(base_Product.getPd_unit());
		temp.setBd_name(base_Product.getPd_bd_name());
		temp.setTp_name(base_Product.getPd_tp_name());
		temp.setCr_name(base_Barcode.getBc_colorname());
		temp.setSz_name(base_Barcode.getBc_sizename());
		temp.setBr_name(base_Barcode.getBc_braname());
		resultMap.put("result", 2);//add
		resultMap.put("temp", temp);
		return resultMap;
	}
	
	@Override
	@Transactional
	public void temp_save(Map<String, Object> params) {
		List<T_Batch_SellList> temps = (List<T_Batch_SellList>)params.get("temps");
		Integer se_type = (Integer)params.get("se_type");
		T_Sys_User user = (T_Sys_User)params.get("user");
		Object pd_code = params.get("pd_code");
		Object unitPrice = params.get("unitPrice");
		if (temps != null && temps.size() > 0) {
			List<T_Batch_SellList> temps_add = new ArrayList<T_Batch_SellList>();
			List<T_Batch_SellList> temps_update = new ArrayList<T_Batch_SellList>();
			List<T_Batch_SellList> temps_del = new ArrayList<T_Batch_SellList>();
			for (T_Batch_SellList item : temps) {
				if ("add".equals(item.getOperate_type())){
					if (item.getSel_amount() > 0) {
						temps_add.add(item);
					}
				}else if("update".equals(item.getOperate_type())){
					if(!item.getSel_amount().equals(0)){
						temps_update.add(item);
					}else {
						temps_del.add(item);
					}
				}
			}
			if (temps_add.size() > 0) {
				batchSellDAO.temp_save(temps_add);
			}
			if (temps_update.size() > 0) {
				batchSellDAO.temp_update(temps_update);
			}
			if (temps_del.size() > 0) {
				batchSellDAO.temp_del(temps_del);
			}
		}
		if (StringUtil.isNotEmpty(pd_code) && StringUtil.isNotEmpty(unitPrice)) {
			batchSellDAO.temp_updateprice(pd_code.toString(),"0", Double.parseDouble(unitPrice.toString()), se_type, user.getUs_id(), user.getCompanyid());
		}
	}
	
	@Override
	@Transactional
	public void temp_import(Map<String, Object> params) {
		List<String[]> datas = (List<String[]>)params.get("datas");
		Integer se_type = (Integer)params.get("se_type");
		T_Sys_User user = (T_Sys_User)params.get("user");
		String ci_code = (String)params.get("ci_code");
		String priceType = (String)params.get("priceType");
		String batch_price = (String)params.get("batch_price");
		Double ci_rate = Double.parseDouble(params.get("ci_rate").toString());
		List<String> barcodes = new ArrayList<String>();
		Map<String, Integer> data_amount = new HashMap<String, Integer>();
		for (String[] data : datas) {
			barcodes.add(data[0]);
			data_amount.put(data[0], Integer.parseInt(data[1]));
		}
		List<T_Batch_Import> imports = batchSellDAO.temp_listByImport(barcodes, priceType, ci_rate, batch_price, ci_code, user.getCompanyid());
		if (imports == null || imports.size() == 0) {
			throw new RuntimeException("无数据可导入");
		}
		Map<String, Double> unitPriceMap = new HashMap<String, Double>();
		Map<String, Double> rebatePriceMap = new HashMap<String, Double>();
		Map<String, T_Batch_SellList> tempsMap = new HashMap<String, T_Batch_SellList>();
		List<T_Batch_SellList> temps = batchSellDAO.temp_list_forimport(se_type, user.getUs_id(), user.getCompanyid());
		for (T_Batch_SellList temp : temps) {
			if(!unitPriceMap.containsKey(temp.getSel_pd_code())){
				unitPriceMap.put(temp.getSel_pd_code(), temp.getSel_unitprice());
				rebatePriceMap.put(temp.getSel_pd_code(), temp.getSel_rebateprice());
			}
			tempsMap.put(temp.getSel_sub_code(), temp);
		}
		List<T_Batch_SellList> temps_add = new ArrayList<T_Batch_SellList>();
		List<T_Batch_SellList> temps_update = new ArrayList<T_Batch_SellList>();
		for (T_Batch_Import item : imports) {
			if(tempsMap.containsKey(item.getBc_subcode())){//临时表已存在，更新数量
				T_Batch_SellList temp = tempsMap.get(item.getBc_subcode());
				temp.setSel_amount(temp.getSel_amount()+data_amount.get(item.getBc_barcode()));
				temps_update.add(temp);
			}else {//临时表不存在，新增数据
				T_Batch_SellList temp = new T_Batch_SellList();
				temp.setSel_pd_code(item.getBc_pd_code());
				temp.setSel_sub_code(item.getBc_subcode());
				temp.setSel_sz_code(item.getBc_size());
				temp.setSel_szg_code(item.getPd_szg_code());
				temp.setSel_cr_code(item.getBc_color());
				temp.setSel_br_code(item.getBc_bra());
				temp.setSel_amount(data_amount.get(item.getBc_barcode()));
				if(unitPriceMap.containsKey(item.getBc_pd_code())){//临时表已存在此货号，则使用临时表价格
					temp.setSel_unitprice(unitPriceMap.get(item.getBc_pd_code()));
					temp.setSel_rebateprice(rebatePriceMap.get(item.getBc_pd_code()));
				}else {
					temp.setSel_unitprice(item.getUnit_price());
					temp.setSel_rebateprice(0d);
				}
				temp.setSel_retailprice(item.getRetail_price());
				temp.setSel_costprice(item.getCost_price());
				temp.setSel_remark("");
				temp.setSel_pi_type(0);//商品
				temp.setSel_us_id(user.getUs_id());
				temp.setSel_type(se_type);
				temp.setCompanyid(user.getCompanyid());
				temps_add.add(temp);
			}
		}
		if (temps_add.size() > 0) {
			batchSellDAO.temp_save(temps_add);
		}
		if (temps_update.size() > 0) {
			batchSellDAO.temp_updateById(temps_update);
		}
	}
	
	@Override
	@Transactional
	public void temp_import_order(Map<String, Object> params) {
		String ids = (String)params.get("ids");
		if(StringUtil.isEmpty(ids)){
			throw new IllegalArgumentException("参数ids不能为null");
		}
		List<Long> odl_ids = new ArrayList<Long>();
		String[] idArr = ids.split(",");
		for (String id : idArr) {
			odl_ids.add(Long.parseLong(id));
		}
		Integer se_type = (Integer)params.get("se_type");
		T_Sys_User user = (T_Sys_User)params.get("user");
		List<T_Batch_SellList> details = batchSellDAO.list_order_forimport(odl_ids);
		if (details == null || details.size() == 0) {
			throw new RuntimeException("订单不存在");
		}
		for(T_Batch_SellList item:details){
			item.setSel_us_id(user.getUs_id());
		}
		batchSellDAO.temp_clear(se_type, user.getUs_id(), user.getCompanyid());
		batchSellDAO.temp_save(details);
	}
	
	@Override
	@Transactional
	public void temp_updateAmount(T_Batch_SellList temp) {
		batchSellDAO.temp_update(temp);
	}
	
	@Override
	@Transactional
	public void temp_updatePrice(T_Batch_SellList temp) {
		batchSellDAO.temp_updateprice(temp.getSel_pd_code(), StringUtil.trimString(temp.getSel_pi_type()),
				temp.getSel_unitprice(), temp.getSel_type(),
				temp.getSel_us_id(), temp.getCompanyid());
	}
	
	@Override
	@Transactional
	public void temp_updateRebatePrice(T_Batch_SellList temp) {
		batchSellDAO.temp_updaterebateprice(temp.getSel_pd_code(),temp.getSel_rebateprice(), temp.getSel_type(),
				temp.getSel_us_id(), temp.getCompanyid());
	}
	
	@Override
	@Transactional
	public void temp_updateRemarkById(T_Batch_SellList temp) {
		batchSellDAO.temp_updateRemarkById(temp);
	}
	
	@Override
	@Transactional
	public void temp_updateRemarkByPdCode(T_Batch_SellList temp) {
		batchSellDAO.temp_updateRemarkByPdCode(temp);
	}
	
	@Override
	@Transactional
	public void temp_del(Integer sel_id) {
		batchSellDAO.temp_del(sel_id);
	}

	@Override
	@Transactional
	public void temp_delByPiCode(T_Batch_SellList temp) {
		Assert.notNull(temp.getCompanyid(),"连接超时，请重新登录!");
		Assert.notNull(temp.getSel_us_id(),"参数us_id不能为null");
		Assert.notNull(temp.getSel_type(),"参数sel_type不能为null");
		batchSellDAO.temp_delByPiCode(temp);
	}
	
	@Override
	@Transactional
	public void temp_clear(Integer se_type,Integer us_id,Integer companyid) {
		batchSellDAO.temp_clear(se_type, us_id, companyid);;
	}
	
	@Override
	@Transactional
	public void save(T_Batch_Sell sell, T_Sys_User user) {
		Assert.notNull(sell,"参数不能为null");
		Assert.hasText(sell.getSe_client_code(),"批发客户不能为空");
		Assert.hasText(sell.getSe_depot_code(),"仓库不能为空");
		Assert.hasText(sell.getSe_manager(),"经办人不能为空");
		sell.setCompanyid(user.getCompanyid());
		sell.setSe_us_id(user.getUs_id());
		sell.setSe_maker(user.getUs_name());
		sell.setSe_ar_state(CommonUtil.AR_STATE_NOTAPPROVE);
		sell.setSe_sysdate(DateUtil.getCurrentTime());
		sell.setSe_isprint(0);
		sell.setSe_pay_state(0);
		
		//TODO信用额度检查
		
		//1.查临时表
		List<T_Batch_SellList> temps = batchSellDAO.temp_list_forsave(sell.getSe_type(), user.getUs_id(), user.getCompanyid());
		if(temps == null || temps.size() == 0){
			throw new RuntimeException("单据已保存，请勿重复提交");
		}
		//2.保存单据
		for(T_Batch_SellList temp:temps){
			if(StringUtil.isNotEmpty(temp.getSel_order_number())){
				sell.setSe_order_number(temp.getSel_order_number());
				break;
			}
		}
		if(sell.getSe_type().equals(1)){//退货
			for (T_Batch_SellList temp : temps) {
				temp.setSel_amount(-Math.abs(temp.getSel_amount()));
			}
		}
		int se_amount = 0;
		double se_money = 0d;
		double se_retailmoney = 0d;
		double se_costmoney = 0d;
		double se_rebatemoney = 0d;
		for (T_Batch_SellList temp : temps) {
			se_amount += temp.getSel_amount();
			se_money += temp.getSel_amount() * temp.getSel_unitprice();
			se_retailmoney += temp.getSel_amount() * temp.getSel_retailprice();
			se_costmoney += temp.getSel_amount() * temp.getSel_costprice();
			se_rebatemoney += temp.getSel_amount() * temp.getSel_rebateprice();
		}
		sell.setSe_amount(se_amount);
		sell.setSe_money(se_money);
		sell.setSe_retailmoney(se_retailmoney);
		sell.setSe_costmoney(se_costmoney);
		sell.setSe_rebatemoney(se_rebatemoney);
		sell.setSe_discount_money(sell.getSe_discount_money() == null ? 0d : sell.getSe_discount_money());
		sell.setSe_stream_money(sell.getSe_stream_money() == null ? 0d : sell.getSe_stream_money());
		sell.setSe_receivable(sell.getSe_money() - sell.getSe_discount_money() - sell.getSe_rebatemoney() + sell.getSe_stream_money());
		sell.setSe_received(0d);
		sell.setSe_prepay(0d);
		batchSellDAO.save(sell, temps);
		//3.删除临时表
		batchSellDAO.temp_clear(sell.getSe_type(), user.getUs_id(), user.getCompanyid());
	}
	
	@Override
	@Transactional
	public void update(T_Batch_Sell sell, T_Sys_User user) {
		Assert.notNull(sell,"参数不能为null");
		Assert.hasText(sell.getSe_client_code(),"批发客户不能为空");
		Assert.hasText(sell.getSe_depot_code(),"仓库不能为空");
		Assert.hasText(sell.getSe_manager(),"经办人不能为空");
		sell.setCompanyid(user.getCompanyid());
		sell.setSe_us_id(user.getUs_id());
		sell.setSe_maker(user.getUs_name());
		sell.setSe_ar_state(CommonUtil.AR_STATE_NOTAPPROVE);
		sell.setSe_sysdate(DateUtil.getCurrentTime());
		sell.setSe_isprint(0);
		sell.setSe_pay_state(0);
		//1.1查临时表
		List<T_Batch_SellList> temps = batchSellDAO.temp_list_forsave(sell.getSe_type(), user.getUs_id(), user.getCompanyid());
		if(temps == null || temps.size() == 0){
			throw new RuntimeException("单据已保存，请勿重复提交");
		}
		//1.2验证单据
		T_Batch_Sell oldSell = batchSellDAO.check(sell.getSe_number(), user.getCompanyid());
		if (oldSell == null || !CommonUtil.AR_STATE_FAIL.equals(oldSell.getSe_ar_state())) {
			throw new RuntimeException("单据已修改，请勿重复提交");
		}
		//1.3删除子表
		batchSellDAO.deleteList(sell.getSe_number(), user.getCompanyid());
		//2.保存单据
		for(T_Batch_SellList temp:temps){
			if(StringUtil.isNotEmpty(temp.getSel_order_number())){
				sell.setSe_order_number(temp.getSel_order_number());
				break;
			}
		}
		if(sell.getSe_type().equals(1)){//退货
			for (T_Batch_SellList temp : temps) {
				temp.setSel_amount(-Math.abs(temp.getSel_amount()));
			}
		}
		int se_amount = 0;
		double se_money = 0d;
		double se_retailmoney = 0d;
		double se_costmoney = 0d;
		double se_rebatemoney = 0d;
		for (T_Batch_SellList temp : temps) {
			se_amount += temp.getSel_amount();
			se_money += temp.getSel_amount() * temp.getSel_unitprice();
			se_retailmoney += temp.getSel_amount() * temp.getSel_retailprice();
			se_costmoney += temp.getSel_amount() * temp.getSel_costprice();
			se_rebatemoney += temp.getSel_amount() * temp.getSel_rebateprice();
		}
		sell.setSe_amount(se_amount);
		sell.setSe_money(se_money);
		sell.setSe_retailmoney(se_retailmoney);
		sell.setSe_costmoney(se_costmoney);
		sell.setSe_rebatemoney(se_rebatemoney);
		sell.setSe_discount_money(sell.getSe_discount_money() == null ? 0d : sell.getSe_discount_money());
		sell.setSe_stream_money(sell.getSe_stream_money() == null ? 0d : sell.getSe_stream_money());
		sell.setSe_receivable(sell.getSe_money() - sell.getSe_discount_money() - sell.getSe_rebatemoney() + sell.getSe_stream_money());
		sell.setSe_received(0d);
		sell.setSe_prepay(0d);
		batchSellDAO.update(sell, temps);
		//3.删除临时表
		batchSellDAO.temp_clear(sell.getSe_type(), user.getUs_id(), user.getCompanyid());
	}
	
	@Override
	@Transactional
	public T_Batch_Sell approve(String number, T_Approve_Record record, T_Sys_User user) {
		Assert.hasText(number,"参数number不能为null");
		T_Batch_Sell sell = batchSellDAO.check(number, user.getCompanyid());
		Assert.notNull(sell,"单据不存在");
		if(!CommonUtil.AR_STATE_NOTAPPROVE.equals(sell.getSe_ar_state())){
			throw new RuntimeException("单据已经审核");
		}
		T_Batch_Client client = clientDAO.loadClient(sell.getSe_client_code(), user.getCompanyid());
		//TODO 信用额度检查
		
		//更新单据审核状态
		sell.setSe_ar_state(record.getAr_state());
		sell.setSe_ar_date(DateUtil.getCurrentTime());
		if(CommonUtil.AR_STATE_APPROVED.equals(sell.getSe_ar_state())){
			sell.setSe_lastdebt(client.getCi_receivable()-client.getCi_received()-client.getCi_prepay());
		}
		batchSellDAO.updateApprove(sell);
		//保存审核记录表
		record.setAr_number(number);
		record.setAr_sysdate(DateUtil.getCurrentTime());
		record.setAr_us_name(user.getUs_name());
		record.setAr_type("t_batch_sell");
		record.setCompanyid(user.getCompanyid());
		approveRecordDAO.save(record);
		if(!CommonUtil.AR_STATE_APPROVED.equals(sell.getSe_ar_state())){//审核不通过，则直接返回
			return sell;
		}
		//3.审核通过
		//3.1更新订单
		List<T_Batch_SellList> details_order = batchSellDAO.listWithOrder(number, user.getCompanyid());
		if (details_order != null && details_order.size() > 0) {//更新订单子表和主表的已到数量
			Integer totalAmount_order = 0;
			String order_number = details_order.get(0).getSel_order_number();
			for (T_Batch_SellList item : details_order) {
				totalAmount_order += item.getSel_amount();
			}
			T_Batch_Order order = batchSellDAO.loadOrder(order_number, user.getCompanyid());
			if(order != null){
				order.setOd_realamount(order.getOd_realamount()+totalAmount_order);
				Long days = DateUtil.getDaysMinusBetween(order.getOd_delivery_date(), DateUtil.getYearMonthDate());
				if (days > 0) {//超期
					order.setOd_state(order.getOd_realamount() >= order.getOd_amount() ? 3 : 4);
				}else {
					order.setOd_state(order.getOd_realamount() >= order.getOd_amount() ? 1 : 0);
				}
				batchSellDAO.updateOrder(order);
				batchSellDAO.updateOrderList(details_order);
			}
		}
		//3.2保存客户最近批发价
		List<T_Batch_ClientPrice> clientPrices = batchSellDAO.detail_listClientPrice(number, user.getCompanyid());
		if (clientPrices.size() > 0) {
			for (T_Batch_ClientPrice item : clientPrices) {
				item.setCp_ci_code(sell.getSe_client_code());
				item.setCp_sysdate(DateUtil.getCurrentTime());
				item.setCompanyid(user.getCompanyid());
			}
			batchSellDAO.saveClientPrice(clientPrices);
			//客户最近批发价保留10条记录
			batchSellDAO.deleteClientPrice(clientPrices);
		}
		//3.2更新库存
		List<T_Stock_DataBill> stocks = batchSellDAO.listStock(number, sell.getSe_depot_code(), user.getCompanyid());
		List<T_Stock_DataBill> add_stocks = new ArrayList<T_Stock_DataBill>();
		List<T_Stock_DataBill> update_stocks = new ArrayList<T_Stock_DataBill>();
		for (T_Stock_DataBill stock : stocks) {
			if(stock.getSd_id() == null){
				stock.setSd_dp_code(sell.getSe_depot_code());
				stock.setSd_init(0);
				stock.setSd_date(DateUtil.getCurrentTime());
				stock.setCompanyid(user.getCompanyid());
				if(sell.getSe_type().equals(0)){//批发出库
					stock.setSd_amount(-stock.getBill_amount());
				}else {//退货入库
					stock.setSd_amount(stock.getBill_amount());
				}
				add_stocks.add(stock);
			}else {
				if(sell.getSe_type().equals(0)){//批发出库
					stock.setSd_amount(stock.getSd_amount() - stock.getBill_amount());
				}else {//退货入库
					stock.setSd_amount(stock.getSd_amount() + stock.getBill_amount());
				}
				update_stocks.add(stock);
			}
		}
		if (add_stocks.size() > 0) {
			dataDAO.save(add_stocks);
		}
		if (update_stocks.size() > 0) {
			dataDAO.update(update_stocks);
		}
		//3.3更新批发客户财务&生成往来明细账
		client.setCi_receivable(client.getCi_receivable() + sell.getSe_receivable());
		clientDAO.updateReceivable(client);
		T_Batch_Dealings dealings = new T_Batch_Dealings();
		dealings.setDl_client_code(sell.getSe_client_code());
		dealings.setDl_number(sell.getSe_number());
		dealings.setDl_type(sell.getSe_type());
		dealings.setDl_discount_money(sell.getSe_discount_money());
		dealings.setDl_receivable(sell.getSe_receivable());
		dealings.setDl_received(0d);
		dealings.setDl_debt(client.getCi_receivable()-client.getCi_received()-client.getCi_prepay());
		dealings.setDl_date(DateUtil.getCurrentTime());
		dealings.setDl_manager(user.getUs_name());
		dealings.setDl_remark(sell.getSe_remark());
		dealings.setDl_sysdate(DateUtil.getCurrentTime());
		dealings.setDl_batchamount(sell.getSe_amount());
		dealings.setCompanyid(user.getCompanyid());
		batchDealingsDAO.save(dealings);
		//3.4保存物流单
		if (StringUtil.isNotEmpty(sell.getSe_stream_code()) && sell.getSe_stream_money() > 0) {
			T_Base_Stream stream = batchSellDAO.loadStream(sell.getSe_stream_code(), user.getCompanyid());
			if(stream != null){
				if (stream.getSe_payable() == null) {
					stream.setSe_payable(sell.getSe_stream_money());
				} else {
					stream.setSe_payable(stream.getSe_payable() + sell.getSe_stream_money());
				}
				batchSellDAO.updateStream(stream);
				T_Base_Stream_Bill streamBill = new T_Base_Stream_Bill();
				streamBill.setSeb_se_code(stream.getSe_code());
				streamBill.setSeb_date(DateUtil.getCurrentTime());
				streamBill.setSeb_money(sell.getSe_stream_money());
				streamBill.setSeb_discount_money(0d);
				streamBill.setSeb_payable(sell.getSe_stream_money());
				streamBill.setSeb_payabled(0d);
				streamBill.setSeb_pay_state(0);
				streamBill.setSeb_join_number(number);
				streamBill.setSeb_type(1);
				streamBill.setSeb_sysdate(DateUtil.getCurrentTime());
				streamBill.setCompanyid(user.getCompanyid());
				streamBillDAO.save(streamBill);
			}
		}
		return sell;
	}
	
	@Override
	@Transactional
	public T_Batch_Sell reverse(String number, T_Sys_User user) {
		Assert.hasText(number,"参数number不能为null");
		T_Batch_Sell sell = batchSellDAO.check(number, user.getCompanyid());
		if(sell == null){
			throw new RuntimeException("单据不存在");
		}
		if(!CommonUtil.AR_STATE_APPROVED.equals(sell.getSe_ar_state())){
			throw new RuntimeException("单据未审核或审核未通过");
		}
		if(!CommonUtil.PAY_STATE_UNPAY.equals(sell.getSe_pay_state())){
			throw new RuntimeException("该单据已经结算，不能反审核");
		}
		T_Batch_SettleList existSettle = batchSettleDAO.check_settle_bill(sell.getSe_number(), user.getCompanyid());
		if(existSettle != null){
			throw new RuntimeException("该单据已经结算，结算单据["+existSettle.getStl_number()+"]，不能反审核");
		}
		T_Base_Stream_Bill streamBill = null;
		if (StringUtil.isNotEmpty(sell.getSe_stream_code()) && sell.getSe_stream_money() > 0) {
			streamBill = streamBillDAO.loadByJoinNumber(number, user.getCompanyid());
			if (streamBill != null) {
				if(!CommonUtil.PAY_STATE_UNPAY.equals(streamBill.getSeb_pay_state())){
					throw new RuntimeException("物流单已结算，不能反审核该单据");
				}
			}
		}
		//1.更新单据审核状态
		sell.setSe_ar_state(CommonUtil.AR_STATE_NOTAPPROVE);
		sell.setSe_ar_date(DateUtil.getCurrentTime());
		sell.setSe_lastdebt(null);
		batchSellDAO.updateApprove(sell);
		//2.保存审核记录表
		T_Approve_Record record = new T_Approve_Record();
		record.setAr_state(CommonUtil.AR_STATE_REVERSE_APPROVE);
		record.setAr_describe(user.getUs_name()+"反审核单据");
		record.setAr_number(number);
		record.setAr_sysdate(DateUtil.getCurrentTime());
		record.setAr_us_name(user.getUs_name());
		record.setAr_type("t_batch_sell");
		record.setCompanyid(user.getCompanyid());
		approveRecordDAO.save(record);
		//3.1更新订单
		List<T_Batch_SellList> details_order = batchSellDAO.listWithOrder(number, user.getCompanyid());
		if (details_order != null && details_order.size() > 0) {//更新订单子表和主表的已到数量
			Integer totalAmount_order = 0;
			String order_number = details_order.get(0).getSel_order_number();
			for (T_Batch_SellList item : details_order) {
				totalAmount_order += item.getSel_amount();
			}
			T_Batch_Order order = batchSellDAO.loadOrder(order_number, user.getCompanyid());
			if(order != null){
				order.setOd_realamount(order.getOd_realamount()-totalAmount_order);
				Long days = DateUtil.getDaysMinusBetween(order.getOd_delivery_date(), DateUtil.getYearMonthDate());
				if (days > 0) {//超期
					order.setOd_state(order.getOd_realamount() >= order.getOd_amount() ? 3 : 4);
				}else {
					order.setOd_state(order.getOd_realamount() >= order.getOd_amount() ? 1 : 0);
				}
				batchSellDAO.updateOrder(order);
				batchSellDAO.updateOrderList_Reverse(details_order);
			}
		}
		
		//3.2更新库存
		List<T_Stock_DataBill> stocks = batchSellDAO.listStock(number, sell.getSe_depot_code(), user.getCompanyid());
		List<T_Stock_DataBill> add_stocks = new ArrayList<T_Stock_DataBill>();
		List<T_Stock_DataBill> update_stocks = new ArrayList<T_Stock_DataBill>();
		for (T_Stock_DataBill stock : stocks) {
			if(stock.getSd_id() == null){
				stock.setSd_dp_code(sell.getSe_depot_code());
				stock.setSd_init(0);
				stock.setSd_date(DateUtil.getCurrentTime());
				stock.setCompanyid(user.getCompanyid());
				if(sell.getSe_type().equals(0)){//批发出库
					stock.setSd_amount(stock.getBill_amount());
				}else {//退货入库
					stock.setSd_amount(-stock.getBill_amount());
				}
				add_stocks.add(stock);
			}else {
				if(sell.getSe_type().equals(0)){//批发出库
					stock.setSd_amount(stock.getSd_amount() + stock.getBill_amount());
				}else {//退货入库
					stock.setSd_amount(stock.getSd_amount() - stock.getBill_amount());
				}
				update_stocks.add(stock);
			}
		}
		if (add_stocks.size() > 0) {
			dataDAO.save(add_stocks);
		}
		if (update_stocks.size() > 0) {
			dataDAO.update(update_stocks);
		}
		//3.3更新批发客户财务&删除往来明细账
		T_Batch_Client client = clientDAO.loadClient(sell.getSe_client_code(), user.getCompanyid());
		if (client != null) {
			client.setCi_receivable(client.getCi_receivable() - sell.getSe_receivable());
			clientDAO.updateReceivable(client);
			T_Batch_Dealings dealings = new T_Batch_Dealings();
			dealings.setDl_client_code(sell.getSe_client_code());
			dealings.setDl_number(sell.getSe_number());
			dealings.setDl_type(sell.getSe_type());
			dealings.setDl_discount_money(-sell.getSe_discount_money());
			dealings.setDl_receivable(-sell.getSe_receivable());
			dealings.setDl_received(0d);
			dealings.setDl_debt(client.getCi_receivable()-client.getCi_received()-client.getCi_prepay());
			dealings.setDl_date(DateUtil.getCurrentTime());
			dealings.setDl_manager(user.getUs_name());
			dealings.setDl_remark("反审核恢复账目往来明细");
			dealings.setDl_sysdate(DateUtil.getCurrentTime());
			dealings.setDl_batchamount(-sell.getSe_amount());
			dealings.setCompanyid(user.getCompanyid());
			batchDealingsDAO.save(dealings);
		}
		//3.4删除物流单
		if(streamBill != null){
			T_Base_Stream stream = batchSellDAO.loadStream(sell.getSe_stream_code(), user.getCompanyid());
			if(stream != null){
				stream.setSe_payable(stream.getSe_payable() - sell.getSe_stream_money());
				batchSellDAO.updateStream(stream);
				streamBillDAO.delete(streamBill.getSeb_id());
			}
		}
		return sell;
	}
	
	@Override
	@Transactional
	public void initUpdate(String number,Integer se_type, Integer us_id, Integer companyid) {
		List<T_Batch_SellList> details = batchSellDAO.detail_list_forsavetemp(number, companyid);;
		for(T_Batch_SellList item:details){
			item.setSel_us_id(us_id);
		}
		batchSellDAO.temp_clear(se_type, us_id, companyid);
		batchSellDAO.temp_save(details);
	}
	
	@Override
	@Transactional
	public void del(String number, Integer companyid) {
		Assert.hasText(number,"参数number不能为null");
		T_Batch_Sell sell = batchSellDAO.check(number, companyid);
		if(sell == null){
			throw new RuntimeException("单据不存在");
		}
		if(!CommonUtil.AR_STATE_NOTAPPROVE.equals(sell.getSe_ar_state()) && !CommonUtil.AR_STATE_FAIL.equals(sell.getSe_ar_state())){
			throw new RuntimeException("单据已审核通过不能删除！");
		}
		batchSellDAO.del(number, companyid);
	}
	
	@Override
	public Map<String, Object> loadPrintData(String number, Integer sp_id, Integer displayMode,T_Sys_User user) {
		Map<String, Object> resultMap = printDAO.loadPrint4Bill(sp_id);
		T_Batch_Sell sell = batchSellDAO.load(number, user.getCompanyid());
		List<T_Batch_SellList> sellList = null;
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("sel_number", number);
		params.put("companyid", user.getCompanyid());
		if(displayMode.intValue() == 2){//汇总模式
			sellList = batchSellDAO.detail_sum(params);
		}else {
			sellList = batchSellDAO.detail_list_print(params);
		}
		resultMap.put("sell", sell);
		resultMap.put("sellList", sellList);
		resultMap.put("client", clientDAO.load(sell.getSe_client_code(), user.getCompanyid()));
		if(displayMode.intValue() == 1){//尺码模式查询
			List<String> szgCodes = new ArrayList<String>();
			for (T_Batch_SellList item : sellList) {
				if(!szgCodes.contains(item.getSel_szg_code())){
					szgCodes.add(item.getSel_szg_code());
				}
			}
			List<T_Base_SizeList> sizeGroupList = sizeDAO.listBySzg(szgCodes, user.getCompanyid());
			resultMap.put("sizeGroupList", sizeGroupList);
		}
		return resultMap;
	}
	
}
